#include "wordLogic.h"
#include <stdarg.h>

Bool VirtualNode(int count, ...) {
	if(count<=0) return false;
  va_list args;
  va_start(args, count);

  for(int i = 0; i < count; ++i) {
    int16_t value = va_arg(args, int); // bool 被提升为 int
    if(value>0) {
      va_end(args);
      return true;
    }
  }

  va_end(args);
  return false;
}


Bool BitwiseOr(Bool en, void* out, size_t size, int count, ...) {
  if(!en || !out || count <= 0)
    return false;
  va_list args;
  va_start(args, count);
  switch(size) {
    case 1: {
      uint8_t result = 0;
      for(int i = 0; i < count; ++i) {
        uint8_t* in = va_arg(args, uint8_t*);
        if(in)
          result |= *in;
      }
      *(uint8_t*) out = result;
      break;
    }
    case 2: {
      uint16_t result = 0;
      for(int i = 0; i < count; ++i) {
        uint16_t* in = va_arg(args, uint16_t*);
        if(in)
          result |= *in;
      }
      *(uint16_t*) out = result;
      break;
    }
    case 4: {
      uint32_t result = 0;
      for(int i = 0; i < count; ++i) {
        uint32_t* in = va_arg(args, uint32_t*);
        if(in)
          result |= *in;
      }
      *(uint32_t*) out = result;
      break;
    }
    default:
      va_end(args);
      return false;
  }
  va_end(args);
  return true;
}

Bool BitwiseAnd(Bool en, void* out, size_t size, int count, ...) {
  if(!en || !out || count <= 0)
    return false;
  va_list args;
  va_start(args, count);
  switch(size) {
    case 1: {
      uint8_t result = 0xFF;
      for(int i = 0; i < count; ++i) {
        uint8_t* in = va_arg(args, uint8_t*);
        if(in)
          result &= *in;
      }
      *(uint8_t*) out = result;
      break;
    }
    case 2: {
      uint16_t result = 0xFFFF;
      for(int i = 0; i < count; ++i) {
        uint16_t* in = va_arg(args, uint16_t*);
        if(in)
          result &= *in;
      }
      *(uint16_t*) out = result;
      break;
    }
    case 4: {
      uint32_t result = 0xFFFFFFFF;
      for(int i = 0; i < count; ++i) {
        uint32_t* in = va_arg(args, uint32_t*);
        if(in)
          result &= *in;
      }
      *(uint32_t*) out = result;
      break;
    }
    default:
      va_end(args);
      return false;
  }
  va_end(args);
  return true;
}

Bool BitwiseXor(Bool en, void* out, size_t size, int count, ...) {
  if(!en || !out || count <= 0)
    return false;
  va_list args;
  va_start(args, count);
  switch(size) {
    case 1: {
      uint8_t result = 0;
      for(int i = 0; i < count; ++i) {
        uint8_t* in = va_arg(args, uint8_t*);
        if(in)
          result ^= *in;
      }
      *(uint8_t*) out = result;
      break;
    }
    case 2: {
      uint16_t result = 0;
      for(int i = 0; i < count; ++i) {
        uint16_t* in = va_arg(args, uint16_t*);
        if(in)
          result ^= *in;
      }
      *(uint16_t*) out = result;
      break;
    }
    case 4: {
      uint32_t result = 0;
      for(int i = 0; i < count; ++i) {
        uint32_t* in = va_arg(args, uint32_t*);
        if(in)
          result ^= *in;
      }
      *(uint32_t*) out = result;
      break;
    }
    default:
      va_end(args);
      return false;
  }
  va_end(args);
  return true;
}

Bool BitwiseNot(Bool en, void* out, const void* in, size_t size) {
  if(!en || !out || !in)
    return false;
  switch(size) {
    case 1:
      *(uint8_t*) out = ~(*(uint8_t*) in);
      break;
    case 2:
      *(uint16_t*) out = ~(*(uint16_t*) in);
      break;
    case 4:
      *(uint32_t*) out = ~(*(uint32_t*) in);
      break;
    default:
      return false;
  }
  return true;
}
Bool BitwiseOr_Byte(Bool en, Byte* out, int count, ...) {
  if(!en || !out || count <= 0)
    return false;
  va_list args;
  va_start(args, count);
  uint8_t result = 0;
  for(int i = 0; i < count; ++i) {
    uint8_t in = (uint8_t) va_arg(args, int);
      result |= in;
  }
  *out = result;
  va_end(args);
  return true;
}
Bool BitwiseOr_Word(Bool en, Word* out, int count, ...) {
  if(!en || !out || count <= 0)
    return false;
  va_list args;
  va_start(args, count);
  uint16_t result = 0;
  for(int i = 0; i < count; ++i) {
    uint16_t in = (uint16_t) va_arg(args, int);
      result |= in;
  }
  *out = result;
  va_end(args);
  return true;
}
Bool BitwiseOr_DWord(Bool en, DWord* out, int count, ...) {
  if(!en || !out || count <= 0)
    return false;
  va_list args;
  va_start(args, count);
  uint32_t result = 0;
  for(int i = 0; i < count; ++i) {
    uint32_t in = (uint32_t) va_arg(args, uint32_t);
      result |= in;
  }
  *out = result;
  va_end(args);
  return true;
}

Bool BitwiseAnd_Byte(Bool en, Byte* out, int count, ...) {
  if(!en || !out || count <= 0)
    return false;
  va_list args;
  va_start(args, count);
  uint8_t result = 0xFF;
  for(int i = 0; i < count; ++i) {
    uint8_t in = (uint8_t) va_arg(args, int);
      result &= in;
  }
  *out = result;
  va_end(args);
  return true;
}
Bool BitwiseAnd_Word(Bool en, Word* out, int count, ...) {
  if(!en || !out || count <= 0)
    return false;
  va_list args;
  va_start(args, count);
  uint16_t result = 0xFFFF;
  for(int i = 0; i < count; ++i) {
    uint16_t in = (uint16_t) va_arg(args, int);
      result &= in;
  }
  *out = result;
  va_end(args);
  return true;
}
Bool BitwiseAnd_DWord(Bool en, DWord* out, int count, ...) {
  if(!en || !out || count <= 0)
    return false;
  va_list args;
  va_start(args, count);
  uint32_t result = 0xFFFFFFFF;
  for(int i = 0; i < count; ++i) {
    uint32_t in = (uint32_t) va_arg(args, uint32_t);
      result &= in;
  }
  *out = result;
  va_end(args);
  return true;
}

Bool BitwiseXor_Byte(Bool en, Byte* out, int count, ...) {
  if(!en || !out || count <= 0)
    return false;
  va_list args;
  va_start(args, count);
  uint8_t result = 0;
  for(int i = 0; i < count; ++i) {
    uint8_t in = (uint8_t) va_arg(args, int);
      result ^= in;
  }
  *out = result;
  va_end(args);
  return true;
}
Bool BitwiseXor_Word(Bool en, Word* out, int count, ...) {
  if(!en || !out || count <= 0)
    return false;
  va_list args;
  va_start(args, count);
  uint16_t result = 0;
  for(int i = 0; i < count; ++i) {
    uint16_t in = (uint16_t) va_arg(args, int);
      result ^= in;
  }
  *out = result;
  va_end(args);
  return true;
}
Bool BitwiseXor_DWord(Bool en, DWord* out, int count, ...) {
  if(!en || !out || count <= 0)
    return false;
  va_list args;
  va_start(args, count);
  uint32_t result = 0;
  for(int i = 0; i < count; ++i) {
    uint32_t in = (uint32_t) va_arg(args, uint32_t);
      result ^= in;
  }
  *out = result;
  va_end(args);
  return true;
}

Bool BitwiseNot_Byte(Bool en, Byte* out, Byte in) {
  if(!en || !out)
    return false;
  *out = ~in;
  return true;
}
Bool BitwiseNot_Word(Bool en, Word* out, Word in) {
  if(!en || !out)
    return false;
  *out = ~in;
  return true;
}
Bool BitwiseNot_DWord(Bool en, DWord* out, DWord in) {
  if(!en || !out)
    return false;
  *out = ~in;
  return true;
}
